/*
 * @Author: your name
 * @Date: 2022-02-04 21:41:58
 * @LastEditTime: 2022-02-04 22:39:52
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: \ts\13类型断言.ts
 */
// 举例说明

// 1.<类型>值 

// let someValue: any = "this is a string"; let strLength: number = (<string>someValue).length;

// 2.值 as 类型

// let someValue: any = "this is a string"; let strLength: number = (someValue as string).length;

// 1.联合类型可以被断言为其中一个类型
// 2.父类可以被断言为子类
// 3.任何类型都可以被断言为any
// 4.any可以被断言为任何类型
// 5.要使得A能够被断言为B，需要A兼容B或B兼容A

// 1.联合类型可以被断言为其中一个类型
interface Cat {
    name:string;
    run():void;
}
interface Fish {
    name:string;
    eat:string;
    swim():void;
}
function getName(animal:Cat|Fish):string{
    // return animal.name;
    // return animal.eat
    // if(animal.eat) {

    // }
    // return (animal as Fish).name
    return (animal as Fish).eat
    
}
function isFish(animal:Cat|Fish):boolean{
    return (typeof (animal as Fish).swim) === "function";
}

console.log(getName({name:'1',eat:'w',swim() {}}))
console.log(getName({name:'1',run() {},eat:'ss'}))
console.log(isFish({name:'1',eat:'w',swim() {}}))


// 2.将一个父类断言为更加具体的子类
class ApiError extends Error{
    code:number = 0;
}
class HttpError extends Error{
    statusCode:number = 200;
}
// 父类Error并没有code属性，会直接报错，所以需要将其断言为子类ApiError。
function isApiError(error:Error){
    return (typeof (error as ApiError).code === "number");
}


// 2.3 将任何一个类型断言为any
(globalThis as any).a = '123'
// console.log(globalThis)

// 2.4 将any断言为一个具体的类型, 

let ss:any = '123'
// let s:any = 123  需要是string,number不行，断言只是根据已有类型推断成一个，告示编译器当前是什么类型
console.log('长度',(ss as string).length)


// 5.要使得A能够被断言为B，需要A兼容B或B兼容A
interface Animal {
    name:string;
}
interface Cat1 {
    name:string;
    run():void;
}
const tom:Cat1 = {
    name:"tom",
    run(){
        console.log("running");
    }
}
const animal:Animal = tom;
console.log(animal)

// 但结构上可以理解为Cat继承于Animal：
// interface Cat extends Animal{
//     run():void;
// }
// 即：Animal兼容Cat。此时二者可以互相断言：属性少兼容属性多，类似父子类

function testAnimal(animal:Animal){
    return animal as Cat
}
function testCat(cat:Cat){
    return cat as Animal;
}

console.log(testAnimal({name:'12'}))






